package cn.tedu.autoshow.passport.service.impl;

import cn.tedu.autoshow.commons.ex.ServiceException;
import cn.tedu.autoshow.commons.pojo.vo.PageData;
import cn.tedu.autoshow.commons.util.PageInfoToPageDataConverter;
import cn.tedu.autoshow.commons.web.ServiceCode;
import cn.tedu.autoshow.passport.mapper.AdminRoleMapper;
import cn.tedu.autoshow.passport.mapper.RoleMapper;
import cn.tedu.autoshow.passport.mapper.RolePermissionMapper;
import cn.tedu.autoshow.passport.pojo.entity.AdminRole;
import cn.tedu.autoshow.passport.pojo.entity.Role;
import cn.tedu.autoshow.passport.pojo.entity.RolePermission;
import cn.tedu.autoshow.passport.pojo.param.RoleAddNewParam;
import cn.tedu.autoshow.passport.pojo.param.RoleUpdateParam;
import cn.tedu.autoshow.passport.pojo.vo.RoleListItemVO;
import cn.tedu.autoshow.passport.pojo.vo.RoleStandardVO;
import cn.tedu.autoshow.passport.service.IRoleService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class RoleServiceImpl implements IRoleService {

    @Autowired
    private RoleMapper mapper;
    @Autowired
    private AdminRoleMapper adminRoleMapper;
    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    @Override
    public void addNew(RoleAddNewParam roleAddNewParam) {
        log.info("开始:【新增角色】");
        log.debug("传入参数,roleAddNewParam={}", roleAddNewParam);
        //检查角色名称是否被占用，如果被占用，则抛出异常
        QueryWrapper<Role> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("name",roleAddNewParam.getName());
        int countByName = mapper.selectCount(queryWrapper2);
        log.info("规则：根据角色名称检索数据库结果,countByName={}", countByName);
        if(countByName > 0){
            log.info("结果2:不满足角色新增规则【角色名不可重复】，抛出自定异常...");
            throw new ServiceException(ServiceCode.ERR_CONFLICT, "添加角色失败，角色名已存在！");
        }

        log.info("满足角色新增规则，开始新增...");
        log.info("新增角色数据...");
        //名称未占用，添加角色到数据库
        Role role = new Role();
        BeanUtils.copyProperties(roleAddNewParam,role);
        role.setGmtCreate(LocalDateTime.now()).setGmtModified(LocalDateTime.now());

        log.debug("新增角色数据,role={}", role);
        int rows = mapper.insert(role);
        if(rows != 1){
            log.info("结果1:数据返回行数不满足预估行数，预估={}, 实际={}, 抛出自定异常...", 1, rows);
            String message = "添加角色失败，服务器忙，请稍后再试！";
            throw new ServiceException(ServiceCode.ERR_INSERT, message);
        }
        log.info("结果1:新增角色结果,rows={}", rows);

        log.info("新增角色权限关系数据...");
        Long[] permissionIds = roleAddNewParam.getPermissionIds();
        RolePermission[] rolePermissions = new RolePermission[permissionIds.length];
        LocalDateTime now = LocalDateTime.now();
        for (int i = 0; i < rolePermissions.length; i++) {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(role.getId()).setPermissionId(permissionIds[i])
                    .setGmtCreate(now).setGmtModified(now);
            rolePermissions[i] = rolePermission;
        }
        log.debug("新增角色权限关系数据,rolePermissions={}", rolePermissions);
        rows = rolePermissionMapper.insertBatch(rolePermissions);
        if(rows != permissionIds.length){
            log.info("结果1:数据返回行数不满足预估行数，预估={}, 实际={}, 抛出自定异常...", permissionIds.length, rows);
            String message = "添加角色失败，服务器忙，请稍后再试！";
            throw new ServiceException(ServiceCode.ERR_INSERT, message);
        }
        log.info("结果1:新增角色角色关系结果,rows={}", rows);
    }

    @Override
    public void deleteById(Long id) {
        log.info("开始:【删除角色】");
        log.debug("传入参数,id={}", id);
        //根据角色ID检查角色是否存在数据，如果不存在，则抛出异常
        QueryWrapper<Role> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("id", id);
        int countById = mapper.selectCount(queryWrapper2);
        log.info("规则：根据角色id检索数据库结果,countById={}", countById);
        if(countById == 0){
            log.info("结果2:根据角色id检索数据量为0，抛出异常...");
            String message = "删除角色失败，角色数据不存在！";
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        //根据角色ID检查角色是否被使用，如果已被使用，则抛出异常
        QueryWrapper<AdminRole> queryWrapper3 = new QueryWrapper<>();
        queryWrapper3.eq("role_id", id);
        countById = adminRoleMapper.selectCount(queryWrapper3);
        log.info("规则：根据角色id检索数据库结果,countById={}", countById);
        if(countById != 0){
            log.info("结果3:根据角色id检索数据量不为0，抛出异常...");
            String message = "删除角色失败，角色已被使用！";
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        log.info("删除角色数据...");
        int rows = mapper.deleteById(id);
        if(rows != 1){
            log.info("结果1:数据返回行数不满足预估行数，预估={}, 实际={}, 抛出自定异常...", 1, rows);
            String message = "删除角色失败，服务器忙，请稍后再试！";
            throw new ServiceException(ServiceCode.ERR_DELETE, message);
        }
        log.info("结果1:删除角色结果,rows={}", rows);

        log.info("删除角色权限关系数据...");
        rows = rolePermissionMapper.deleteByRoleId(id);
        log.info("结果1:删除角色权限关系结果,rows={}", rows);
    }

    @Override
    public void updateInfoById(Long id, RoleUpdateParam roleUpdateParam) {
        log.info("开始:【更新角色信息】");
        log.debug("传入参数,id={}", id);
        //检查角色ID检查角色是否存在数据，如果不存在，则抛出异常
        QueryWrapper<Role> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("id", id);
        int countById = mapper.selectCount(queryWrapper2);
        log.info("规则：根据角色id检索数据库结果,countById={}", countById);
        if(countById == 0){
            log.info("结果2:根据角色id检索数据量为0，抛出异常...");
            String message = "更新角色失败，角色数据不存在！";
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        //检查角色名称是否被占用，如果被占用，则抛出异常
        QueryWrapper<Role> queryWrapper3 = new QueryWrapper<>();
        queryWrapper2.eq("name",roleUpdateParam.getName());
        queryWrapper2.ne("id",id);
        int countByName = mapper.selectCount(queryWrapper2);
        log.info("规则：根据角色名称检索数据库结果,countByName={}", countByName);
        if(countByName > 0){
            log.info("结果3:不满足角色新增规则【角色名不可重复】，抛出自定异常...");
            String message = "修改角色失败，角色名已存在！";
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        Role role = new Role();
        BeanUtils.copyProperties(roleUpdateParam, role);
        role.setId(id);
        int rows = mapper.updateById(role);
        if(rows != 1){
            log.info("结果1:数据返回行数不满足预估行数，预估={}, 实际={}, 抛出自定异常...", 1, rows);
            String message = "编辑角色失败，服务器忙，请稍后再试！";
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
        log.info("结果1:根据id编辑角色结果,rows={}", rows);
    }

    @Override
    public RoleStandardVO getStandardById(Long id) {
        log.info("开始:【根据ID查询角色】");
        log.debug("传入参数,id={}", id);
        RoleStandardVO standardById = mapper.getStandardById(id);

        //根据角色ID检查角色是否存在数据，如果不存在，则抛出异常
        if(standardById==null){
            log.info("结果2:根据id查询详情，结果为null，抛出异常...");
            String message = "查询角色详情失败，角色数据不存在";
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        log.info("结果1:查询出数据,standardById");
        return standardById;
    }

    @Override
    public PageData<RoleListItemVO> list(Integer pageNum) {
        Integer pageSize = 5;
        return list(pageNum, pageSize);
    }

    @Override
    public PageData<RoleListItemVO> list(Integer pageNum, Integer pageSize) {
        log.info("开始:【查询-角色-分页】");
        log.debug("传入参数, pageNum={}, pageSize={}", pageNum, pageSize);
        PageHelper.startPage(pageNum, pageSize);
        List<RoleListItemVO> list = mapper.list();
        PageInfo<RoleListItemVO> pageInfo = new PageInfo<>(list);
        PageData<RoleListItemVO> pageData = PageInfoToPageDataConverter.converter(pageInfo);
        log.debug("结果1: 查询结果：pageData={}", pageData);
        return pageData;
    }
}
